執行全域前一刻,做全域的預編譯;執行function前一刻,做function的預編譯。
形參(形式參數)、變數(就是指前面有var let const關鍵字,注意此時不賦值)實參(實際參數)給形參
function(不管body,執行時才看)function和變數這裡才賦值)console.log(fun(12,26,38))
console.log(fun(167,2))
console.log(`a=${a}`)
var a=1;
function fun(a,b,c,d){
	e=7;
	if(c){}else{c=0}
	return `a(${a}),b(${b}),c(${c}),d(${d})e(${e})`
}
console.log(`a=${a}`)
全域執行前一刻,做全域預編譯GO是global object 全局作用域
GO{
	
step1.1 宣告變數  舉例:看到 var a=1,定義a為全域變數,但不賦值
	a : undefined,
step1.2 宣告function 注意:宣告function時,不管他的body
	fun : function fun(a,b,c,d){......}
}
全域預編譯結束,執行全域執行 - 看一行 執行一行step2.1 看到console.log(fun(12,26,38)),執行fun function
console.log(fun(12,26,38))
function fun(a,b,c,d){
	e=7;
	if(c){}else{c=0}
	return `a(${a})+b(${b})+c(${c})+d(${d})`
}
fun function的前一刻,做fun function區域預編譯AO是activation object 局部作用域、活躍對象
為甚麼叫活躍對象,是因為function他在跑的時候,AO才存在,function結束,AO消失
step3.1 宣告形參
fun AO{
	a : undefined,
	b : undefined,
	c : undefined,
	d : undefined
}
宣告變數 沒有變數宣告
注意:e=7;前面沒有var let const關鍵字,不是需要宣告的變數
step3.2 賦值:實參給形參
fun AO{
	a : 12,
	b : 26,
	c : 38,
	d : undefined
}
step3.3 宣告function fun中沒有function需要宣告
function區域預編譯結束,執行console.log(fun(12,26,38)) - 看一行 執行一行step4.1 e=7; 變數的前面沒有 var let const,被判定為全域變數
小備註:因為已經在執行階段,所以變數不用先是undefined再變成7
GO{
	a : undefined,
	fun : function fun(a,b,c,d){......},
	e : 7
}
step4.2 執行完return,AO銷毀
console.log(fun(167,2)) - 只講不一樣的GO{
	a : undefined,
	fun : function fun(a,b,c,d){......},
	e : 7
}
fun AO{
	a : 167,
	b : 2,
	c : undefined,
	d : undefined
}
step5.1 if(c){}else{c=0}
因為undefined是falsy,所以跳到else{c=0}
step5.2 fun執行完,AO銷毀
人肉編譯器們,剩下三行了,加油
console.log(`a=${a}`)
var a=1;
console.log(`a=${a}`)
GO{
	a : undefined,
	fun : function fun(a,b,c,d){......},
	e : 7
}
第一個console.log(a=${a})是在「預編譯後,賦值前」,所以a=undefined
第二個console.log(a=${a})是在「賦值後」,所以a=1
剛剛的「實戰gogo」,有看到變數的提升和function的提升。我們稍微總結一下 →
原始值
引用值,會去參照function的body但也不是所有function都會乖乖地提升,那到底是誰怎麼不乖呢?要拜乖乖?